package com.example.routelink.gateway.filter;

import cn.dev33.satoken.secure.SaBase64Util;
import cn.dev33.satoken.secure.SaSecureUtil;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class DecryptRequestBodyFilterGatewayFilterFactory extends BaseFilter<DecryptRequestBodyFilterGatewayFilterFactory.Config> implements Ordered {
    public DecryptRequestBodyFilterGatewayFilterFactory() {
        super(DecryptRequestBodyFilterGatewayFilterFactory.Config.class);
    }
    private final String filterName = "解密Body";

    @Override
    public GatewayFilter apply(DecryptRequestBodyFilterGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            long startTime = System.currentTimeMillis();
            ServerHttpRequest request = exchange.getRequest();
            if (!request.getMethod().equals(HttpMethod.POST)) {
                return chain.filter(exchange);
            }
            String contentType = request.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
            if (contentType == null) {
                return chain.filter(exchange);
            }
            if (contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
                // 解密post参数
                ModifyRequestBodyGatewayFilterFactory.Config modifyRequestConfig = new ModifyRequestBodyGatewayFilterFactory.Config()
                        .setContentType(ContentType.APPLICATION_JSON.getMimeType())
                        .setRewriteFunction(Map.class, Map.class, (exchange1, originalRequestBody) -> {
                            HashMap<String, String> newRequestBody = new HashMap<>();
                            for (Object entry : originalRequestBody.entrySet()) {
                                Map.Entry<String, String> p = (Map.Entry<String, String>) entry;
                                newRequestBody.put(p.getKey(), SaSecureUtil.aesDecrypt(config.secretKey, SaBase64Util.decode(p.getValue())));
                            }
                            writeLog(filterName, startTime, "校验通过,解密之后body {}  ", JSON.toJSONString(newRequestBody));
                            return Mono.just(newRequestBody);
                        });
                return new ModifyRequestBodyGatewayFilterFactory().apply(modifyRequestConfig).filter(exchange, chain);
            }
            return chain.filter(exchange);
        };
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


    @Data
    public static class Config {
        private String type;
        private String secretKey;
    }
}
